Update map_domain_page() documentation (mappings may only be
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Tue, 10 Jan 2006 17:53:44 +0000 (18:53 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Tue, 10 Jan 2006 17:53:44 +0000 (18:53 +0100)
be used within the mapping vcpu). Implement TLB flush
filtering on the per-domain mapcache.

Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/x86_32/domain_page.c
xen/include/asm-x86/domain.h
xen/include/xen/domain_page.h

index 8b28103cf86c2edf2e69608a9935b644a500c58b..b8ca0ab47d1ba54cad992434db855f17f9a56d44 100644 (file)
@@ -40,7 +40,8 @@ void *map_domain_pages(unsigned long pfn, unsigned int order)
 {
     unsigned long va;
     unsigned int idx, i, flags, vcpu = current->vcpu_id;
-    struct mapcache *cache = &current->domain->arch.mapcache;
+    struct domain *d;
+    struct mapcache *cache;
 #ifndef NDEBUG
     unsigned int flush_count = 0;
 #endif
@@ -49,17 +50,24 @@ void *map_domain_pages(unsigned long pfn, unsigned int order)
     perfc_incrc(map_domain_page_count);
 
     /* If we are the idle domain, ensure that we run on our own page tables. */
-    if ( unlikely(is_idle_vcpu(current)) )
+    d = current->domain;
+    if ( unlikely(is_idle_domain(d)) )
         __sync_lazy_execstate();
 
+    cache = &d->arch.mapcache;
+
     spin_lock(&cache->lock);
 
     /* Has some other CPU caused a wrap? We must flush if so. */
-    if ( cache->epoch != cache->shadow_epoch[vcpu] )
+    if ( unlikely(cache->epoch != cache->shadow_epoch[vcpu]) )
     {
-        perfc_incrc(domain_page_tlb_flush);
-        local_flush_tlb();
         cache->shadow_epoch[vcpu] = cache->epoch;
+        if ( NEED_FLUSH(tlbflush_time[smp_processor_id()],
+                        cache->tlbflush_timestamp) )
+        {
+            perfc_incrc(domain_page_tlb_flush);
+            local_flush_tlb();
+        }
     }
 
     do {
@@ -71,6 +79,7 @@ void *map_domain_pages(unsigned long pfn, unsigned int order)
             perfc_incrc(domain_page_tlb_flush);
             local_flush_tlb();
             cache->shadow_epoch[vcpu] = ++cache->epoch;
+            cache->tlbflush_timestamp = tlbflush_current_time();
         }
 
         flags = 0;
index 0a29f61b1cbdd931422f9f866804a600c5e77912..b9955c02499453e040b10e15cb788ca8397ba01d 100644 (file)
@@ -17,6 +17,7 @@ struct mapcache {
     l1_pgentry_t *l1tab;
     unsigned int cursor;
     unsigned int epoch, shadow_epoch[MAX_VIRT_CPUS];
+    u32 tlbflush_timestamp;
     spinlock_t lock;
 };
 
index 8e0a524a420eb7c5df344a5d00b892a550aa57a8..8fbd9ffaa73928450a212e567abab98c89b3afac 100644 (file)
 
 /*
  * Maps a given range of page frames, returning the mapped virtual address. The
- * pages are now accessible within the current domain until a corresponding
+ * pages are now accessible within the current VCPU until a corresponding
  * call to unmap_domain_page().
  */
 extern void *map_domain_pages(unsigned long pfn, unsigned int order);
 
 /*
  * Pass a VA within the first page of a range previously mapped in the context
- * of the currently-executing domain via a call to map_domain_pages(). Those
+ * of the currently-executing VCPU via a call to map_domain_pages(). Those
  * pages will then be removed from the mapping lists.
  */
 extern void unmap_domain_pages(void *va, unsigned int order);
 
 /*
  * Similar to the above calls, except the mapping is accessible in all
- * address spaces (not just within the domain that created the mapping). Global
+ * address spaces (not just within the VCPU that created the mapping). Global
  * mappings can also be unmapped from any context.
  */
 extern void *map_domain_page_global(unsigned long pfn);